﻿using BacklogParser.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace BacklogParser.Parsers
{
    public static class RelatedDocumentParse
    {
        public static RelatedDocument Parse(XElement document)
        {
            var result = new RelatedDocument();

            var division = document.Descendants(Constants.Epo + "division").FirstOrDefault();
            var continuation = document.Descendants(Constants.Epo + "continuation").FirstOrDefault();
            var previouslyFiledApplication = document.Descendants(Constants.Epo + "previously-filed-application").FirstOrDefault();

            if (division != null)
            {
                var relation = division.Descendants(Constants.Epo + "relation").First();

                var parentDoc = relation.Descendants(Constants.Epo + "parent-doc").First();
                var childDoc = relation.Descendants(Constants.Epo + "child-doc").First();

                var childDocument = ParseDocument(childDoc);

                var childStatus = childDoc.Descendants(Constants.Epo + "child-status").FirstOrDefault();
                var childGrantDocument = childDoc.Descendants(Constants.Epo + "child-grant-document").FirstOrDefault();
                var childPctDocument = childDoc.Descendants(Constants.Epo + "child-pct-document").FirstOrDefault();

                if (childStatus != null)
                    childDocument.ChildStatus = childStatus.Value;

                if (childGrantDocument != null)
                    childDocument.ChildGrantDocument = childGrantDocument.Value;

                if (childPctDocument != null)
                    childDocument.ChildPctDocument = childPctDocument.Value;

                Doc parentDocument = ParseDocument(parentDoc);

                var parentStatus = childDoc.Descendants(Constants.Epo + "parent-status").FirstOrDefault();
                var parentGrantDocument = childDoc.Descendants(Constants.Epo + "parent-grant-document").FirstOrDefault();
                var parentPctDocument = childDoc.Descendants(Constants.Epo + "parent-pct-document").FirstOrDefault();


                if (parentStatus != null)
                    parentDocument.ParentStatus = parentStatus.Value;

                if (parentGrantDocument != null)
                    parentDocument.ParentGrantDocument = parentGrantDocument.Value;

                if (parentPctDocument != null)
                    parentDocument.ParentPctDocument = parentPctDocument.Value;

                result.Relation = new Relation
                {
                    ChildDoc = childDocument,
                    ParentDoc = parentDocument
                };
            }

            if (continuation != null)
            {
                result.Continuation = continuation.Value;
            }

            if (previouslyFiledApplication != null)
            {
                var previousDocuments = previouslyFiledApplication.Descendants(Constants.Epo + "document-id").ToList().Select(x => x.Descendants(Constants.Epo + "doc-number").First().Value);

                result.PreviouslyFiledApplication = string.Join(", ", previousDocuments);
            }



            return result;
        }

        private static Doc ParseDocument(XElement parentDoc)
        {
            var kind = parentDoc.Descendants(Constants.Epo + "kind").FirstOrDefault();
            var country = parentDoc.Descendants(Constants.Epo + "country").FirstOrDefault();
            var date = parentDoc.Descendants(Constants.Epo + "date").FirstOrDefault();
            var docNumber = parentDoc.Descendants(Constants.Epo + "doc-number").FirstOrDefault();

            var docId = new DocumentId();

            if (kind != null)
                docId.Kind = kind.Value;
            if (country != null)
                docId.Country = country.Value;
            if (date != null)
                docId.Date = date.Value;
            if (docNumber != null)
                docId.DocNumber = docNumber.Value;

            return new Doc
            {
                DocumentIds = docId
            };
        }
    }

    public class Relation
    {
        public Relation()
        {
            this.ChildDoc = new Doc();
            this.ParentDoc = new Doc();
        }
        public Doc ParentDoc { get; set; }

        public Doc ChildDoc { get; set; }

        public override string ToString()
        {
            return ParentDoc.ToString() + ChildDoc.ToString();
        }
    }

    public class Doc
    {
        public Doc()
        {
            this.DocumentIds = new DocumentId();
        }
        public DocumentId DocumentIds { get; set; }

        public string ChildStatus { get; set; }

        public string ChildGrantDocument { get; set; }

        public string ChildPctDocument { get; set; }

        public string ParentGrantDocument { get; set; }

        public string ParentPctDocument { get; set; }

        public string ParentStatus { get; set; }

        public override string ToString()
        {
            var builder = new StringBuilder();
            builder.AppendLine(DocumentIds.ToString());

            if (!string.IsNullOrEmpty(ChildStatus))
                builder.AppendLine(string.Format("           ChildStatus {0}", this.ChildStatus));

            if (!string.IsNullOrEmpty(ChildGrantDocument))
                builder.AppendLine(string.Format("           ChildGrantDocument {0}", this.ChildGrantDocument));

            if (!string.IsNullOrEmpty(ChildPctDocument))
                builder.AppendLine(string.Format("           ChildPctDocument {0}", this.ChildPctDocument));

            if (!string.IsNullOrEmpty(ParentStatus))
                builder.AppendLine(string.Format("           ParentStatus {0}", this.ParentStatus));

            if (!string.IsNullOrEmpty(ParentPctDocument))
                builder.AppendLine(string.Format("           ParentPctDocument {0}", this.ParentPctDocument));

            if (!string.IsNullOrEmpty(ParentGrantDocument))
                builder.AppendLine(string.Format("           ParentGrantDocument {0}", this.ParentGrantDocument));

            return builder.ToString().Trim();
        }
    }
}
